package com.sharing.util;

/**
 * @author MingTian
 * @version 1.0
 * @description TODO 基于令牌桶算法实现的对请求限流的限制器
 * @date 2023/7/24 15:54
 */
public class LeakyBucketLimiter {
    /**
     * 令牌桶容量
     * 即令牌的最大数量，
     * 代表经过该限制器最大请求频率
     */
    private int capacity = 10;
    private long timeStamp = System.currentTimeMillis();

    public boolean getToken() {
        if (capacity > 0) {
            capacity--;
            return true;
        }
        long current = System.currentTimeMillis();
        if (current - timeStamp >= 100) {
            if ((current - timeStamp) / 100 >= 2) {
                // 假设100ms产生一个令牌
                capacity += (int)((current - timeStamp) / 100) - 1;
            }
            timeStamp = current;
            if (capacity > 10) capacity = 10;
            return true;
        }
        return false;
    }

    public static void main(String[] args) throws InterruptedException {
        LeakyBucketLimiter leakyBucketAlgorithm = new LeakyBucketLimiter();
        while (true) {
            Thread.sleep(100);
            if (leakyBucketAlgorithm.getToken()) {
                System.out.println("获取令牌成功，可以执行业务逻辑了");
            } else {
                System.out.println("获取令牌失败，请稍后重试");
            }
        }
    }
}
